#include "ciphertext.h"

/* *
 * @brief ：Ciphertext 类的默认构造函数
 *
 * 该构造函数初始化 Ciphertext 对象，所有成员变量被初始化为默认值。
 */
Ciphertext::Ciphertext() : ax(nullptr), bx(nullptr), N(0), slots(0), l(0) {}

/* *
 * @brief ：Ciphertext 类的带参构造函数
 *
 * 该构造函数初始化 Ciphertext 对象，使用传入的参数对成员变量进行初始化。
 *
 * @param ax： 指向多项式 a 系数数组的指针。
 * @param bx： 指向多项式 b 系数数组的指针。
 * @param N： 多项式的维度。
 * @param slots： 变量 slots 表示槽位数量，通常在加密算法中用于表示数据的分割。
 * @param l： 表示多项式的层数或长度。
 */
Ciphertext::Ciphertext(uint64_t *ax, uint64_t *bx, long N, long slots, long l)
    : ax(ax), bx(bx), N(N), slots(slots), l(l)
{}

/* *
 * @brief ：Ciphertext 类的拷贝构造函数
 *
 * 该构造函数通过复制另一个 Ciphertext 对象来创建新的 Ciphertext 对象。
 *
 * @param cipher： 需要拷贝的 Ciphertext 对象。
 */
Ciphertext::Ciphertext(const Ciphertext &cipher) : N(cipher.N), slots(cipher.slots), l(cipher.l)
{
    ax = new uint64_t[N * l];
    bx = new uint64_t[N * l];
    for (long i = 0; i < N * l; i++) {
        ax[i] = cipher.ax[i];
        bx[i] = cipher.bx[i];
    }
}

Ciphertext::Ciphertext(long N, long slots, long l)
    : N(N), slots(slots), l(l) {
    ax = new uint64_t[N * l];
    bx = new uint64_t[N * l];
}


/* *
 * @brief ：Ciphertext 类的赋值运算符重载
 *
 * 该运算符重载用于将一个 Ciphertext 对象的内容赋值给另一个 Ciphertext 对象。
 *
 * @param o： 需要赋值的 Ciphertext 对象。
 * @return Ciphertext& ：返回当前对象的引用，以支持链式赋值。
 */
Ciphertext &Ciphertext::operator = (const Ciphertext &o)
{
    if (this == &o) {
        return *this;
    }
    delete[] ax;
    delete[] bx;
    N = o.N;
    l = o.l;
    slots = o.slots;
    ax = new uint64_t[N * l];
    bx = new uint64_t[N * l];
    for (long i = 0; i < N * l; i++) {
        ax[i] = o.ax[i];
        bx[i] = o.bx[i];
    }
    return *this;
}


void Ciphertext::Print() const 
{
    std::cout << "N: " << N << std::endl;
    std::cout << "slots: " << slots << std::endl;
    std::cout << "l: " << l << std::endl;
    std::cout << "ax:" << std::endl;
    for (long i = 0; i < l; i++) {
        for (int j = 0; j < 8; j++) {
            printf("%lu, ", ax[i * N + j]);
        }
        printf("\n");
    }
    std::cout << std::endl;

    std::cout << "bx:" << std::endl;
    for (long i = 0; i < l; i++) {
        for (int j = 0; j < 8; j++) {
            printf("%lu, ", bx[i * N + j]);
        }
        printf("\n");
    }
    std::cout << std::endl;
}